package copyengine.ai.pathFinder
{
	import copyengine.utils.CEActorDirUtils;

	public final class CEPathFinderUtils
	{
		public function CEPathFinderUtils()
		{
		}

		/**
		 * <p>
		 * 优化A*寻路,使得Avtor移动时候尽可能的走直线(及不沿着Tile移动而是像素及的移动),
		 * 及去除结果集中多余的拐点
		 * </p>
		 * <p>
		 * </br>之所以需要指定优化Actor所在的TileX,Y 因为结果数据集里面仅提供了从下一步开始
		 * 如何移动到目标点
		 * </br>比如结果集为(1,3)->(2,3)->(3,4)-(4,5)
		 * </br>则表示下一步先走到(1,3)Tile 但是结果集并没有说明当前所在Tile是哪里。可以为(0,3),(1,2)等等
		 * 此时就无法确认初始方向
		 * </p>
		 *
		 * @param _currentTileIndexX				当前Actor所在的TileIndexX
		 * @param _currentTileIndexY					当前Actor所在的TileInedxY
		 * @param _sourcePackageVector 			优化前的寻路结果
		 *
		 */
		public static function optimizeMovePathPackageVector(_currentTileIndexX:int, _currentTileIndexY:int,
															  _sourcePackageVector:Vector.<CEPathFinderResultPackage>):Vector.<CEPathFinderResultPackage>
		{
			var resultVector:Vector.<CEPathFinderResultPackage> = new Vector.<CEPathFinderResultPackage>();

			//当前优化过的ResultPackage
			var currentOptimizedPackage:CEPathFinderResultPackage = _sourcePackageVector.shift();
			//初始方向
			var initialDir:int = getResutPackageDir(_currentTileIndexX, _currentTileIndexY, currentOptimizedPackage.tileIndexX, currentOptimizedPackage.tileIndexY);
			//突变方向
			var mutationDir:int = int.MIN_VALUE;
			//上一步是否为变异
			var isLastStepMutation:Boolean = false;
			resultVector.push(currentOptimizedPackage);

			//初始化方向在第一次设立后，后续节点就不可以改变 如果不和初始化方向相同，及认为突变
			//突变在第一次设立后也及确定，突变方向和初始方向不可以为同一个坐标系
			//比如原始方向是上下左右之一,则突变方向仅可以为斜上斜下斜左斜右
			//且突变不可以连续出现出现两次,如果两次连续突变则认为方向发生改变
			for (var index:int = 0; index < _sourcePackageVector.length; index++)
			{
				var currentStepDir:int = getResutPackageDir(currentOptimizedPackage.tileIndexX, currentOptimizedPackage.tileIndexY,
															_sourcePackageVector[index].tileIndexX, _sourcePackageVector[index].tileIndexY);

				var isCanContinueOptimized:Boolean = false;

				//第一种情况 和初始方向相同
				if (currentStepDir == initialDir)
				{
					isCanContinueOptimized = true;
				}

				//第二种情况 发生变异但是不是连续变异
				if (isMutationDir(initialDir, currentStepDir))
				{
					if (mutationDir == int.MIN_VALUE)
					{
						isCanContinueOptimized = true;
						mutationDir = currentStepDir;
					}
					else if (currentStepDir == mutationDir && !isLastStepMutation)
					{
						isCanContinueOptimized = true;
					}
					isLastStepMutation = true;
				}
				else
				{
					isLastStepMutation = false;
				}

				if (isCanContinueOptimized)
				{
					currentOptimizedPackage.tileIndexX = _sourcePackageVector[index].tileIndexX;
					currentOptimizedPackage.tileIndexY = _sourcePackageVector[index].tileIndexY;
				}
				else
				{
					//===前面两种情况均不满足及认为当前Step为新的方向
					//新的方向为当前Stpe-上一步Step
					initialDir = getResutPackageDir(currentOptimizedPackage.tileIndexX, currentOptimizedPackage.tileIndexY,
													_sourcePackageVector[index].tileIndexX, _sourcePackageVector[index].tileIndexY);
					currentOptimizedPackage = new CEPathFinderResultPackage();
					currentOptimizedPackage.tileIndexX = _sourcePackageVector[index].tileIndexX;
					currentOptimizedPackage.tileIndexY = _sourcePackageVector[index].tileIndexY;
					isLastStepMutation = false;
					mutationDir = int.MIN_VALUE;
					resultVector.push(currentOptimizedPackage);
				}
			}
			return resultVector;
		}


		private static function getResutPackageDir(_preTileX:int, _preTileY:int, _currentTileX:int, _currentTileY:int):int
		{
			return CEActorDirUtils.getActorDir(_preTileX, _preTileY, _currentTileX, _currentTileY);
		}

		private static function isMutationDir(_normalDir:int, _detectionDir:int):Boolean
		{
			return !CEActorDirUtils.isUnderSameCrossDir(_normalDir, _detectionDir);
		}
	}
}
